"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"jobserver 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "fnv"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "foreign-types"
version = "0.2.0"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "globset"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "hamcrest"
version = "0.1.1"
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "ignore"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "globset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "itoa"
version = "0.3.1"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "same-file"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "scoped-tls"
version = "0.1.0"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "walkdir"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "winapi"
version = "0.2.8"
"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
"checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"
"checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c"
+"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d"
"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
"checksum gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)" = "120d07f202dcc3f72859422563522b66fe6463a4c513df062874daad05f85f0a"
"checksum git2 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa01936ac96555c083c0e8553f672616274408d9d3fc5b8696603fbf63ff43ee"
"checksum git2-curl 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68676bc784bf0bef83278898929bf64a251e87c0340723d0b93fa096c9c5bf8e"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
+"checksum globset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "feeb1b6840809ef5efcf7a4a990bc4e1b7ee3df8cf9e2379a75aeb2ba42ac9c3"
"checksum hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bf088f042a467089e9baa4972f57f9247e42a0cc549ba264c7a04fbb8ecb89d4"
"checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa"
"checksum idna 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2233d4940b1f19f0418c158509cd7396b8d70a5db5705ce410914dc8fa603b37"
+"checksum ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fcaf2365eb14b28ec7603c98c06cc531f19de9eb283d89a3dff8417c8c99f5"
"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
"checksum jobserver 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "443ae8bc0af6c106e6e8b77e04684faecc1a5ce94e058f4c2b0a037b0ea1b133"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
+"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
"checksum semver 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fdd61b85a0fa777f7fb7c454b9189b2941b110d1385ce84d7f76efdf1606a85"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
"checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum wincolor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a39ee4464208f6430992ff20154216ab2357772ac871d994c51628d60e58b8b0"
git2-curl = "0.7"
glob = "0.2"
hex = "0.2"
+ignore = "^0.2.2"
jobserver = "0.1.6"
libc = "0.2"
libgit2-sys = "0.6"
extern crate git2;
extern crate glob;
extern crate hex;
+extern crate ignore;
extern crate jobserver;
extern crate libc;
extern crate libgit2_sys;
use filetime::FileTime;
use git2;
use glob::Pattern;
+use ignore::Match;
+use ignore::gitignore::GitignoreBuilder;
use core::{Package, PackageId, Summary, SourceId, Source, Dependency, Registry};
use ops;
/// The basic assumption of this method is that all files in the directory
/// are relevant for building this package, but it also contains logic to
/// use other methods like .gitignore to filter the list of files.
+ ///
+ /// ## Pattern matching strategy
+ ///
+ /// Migrating from a glob-like pattern matching (using `glob` crate) to a
+ /// gitignore-like pattern matching (using `ignore` crate). The migration
+ /// stages are:
+ ///
+ /// 1) Only warn users about the future change iff their matching rules are
+ /// affected. (CURRENT STAGE)
+ ///
+ /// 2) Switch to the new strategy and upate documents. Still keep warning
+ /// affected users.
+ ///
+ /// 3) Drop the old strategy and no mor warnings.
+ ///
+ /// See <https://github.com/rust-lang/cargo/issues/4268> for more info.
pub fn list_files(&self, pkg: &Package) -> CargoResult<Vec<PathBuf>> {
let root = pkg.root();
+ let no_include_option = pkg.manifest().include().is_empty();
+
+ // glob-like matching rules
- let parse = |p: &String| {
+ let glob_parse = |p: &String| {
Pattern::new(p).map_err(|e| {
- CargoError::from(format!("could not parse pattern `{}`: {}", p, e))
+ CargoError::from(format!("could not parse glob pattern `{}`: {}", p, e))
})
};
- let exclude = pkg.manifest()
- .exclude()
- .iter()
- .map(|p| parse(p))
- .collect::<Result<Vec<_>, _>>()?;
-
- let include = pkg.manifest()
- .include()
- .iter()
- .map(|p| parse(p))
- .collect::<Result<Vec<_>, _>>()?;
-
- let mut filter = |p: &Path| {
- let relative_path = util::without_prefix(p, root).unwrap();
- include.iter().any(|p| p.matches_path(relative_path)) || {
- include.is_empty() &&
- !exclude.iter().any(|p| p.matches_path(relative_path))
+ let glob_exclude = pkg.manifest()
+ .exclude()
+ .iter()
+ .map(|p| glob_parse(p))
+ .collect::<Result<Vec<_>, _>>()?;
+
+ let glob_include = pkg.manifest()
+ .include()
+ .iter()
+ .map(|p| glob_parse(p))
+ .collect::<Result<Vec<_>, _>>()?;
+
+ let glob_should_package = |relative_path: &Path| -> bool {
+ // include and exclude options are mutually exclusive.
+ if no_include_option {
+ !glob_exclude.iter().any(|pattern| {
+ pattern.matches_path(relative_path)
+ })
+ } else {
+ glob_include.iter().any(|pattern| {
+ pattern.matches_path(relative_path)
+ })
+ }
+ };
+
+ // ignore-like matching rules
+
+ let mut exclude_builder = GitignoreBuilder::new(root);
+ for rule in pkg.manifest().exclude() {
+ exclude_builder.add_line(None, rule)?;
+ }
+ let ignore_exclude = exclude_builder.build()?;
+
+ let mut include_builder = GitignoreBuilder::new(root);
+ for rule in pkg.manifest().include() {
+ include_builder.add_line(None, rule)?;
+ }
+ let ignore_include = include_builder.build()?;
+
+ let ignore_should_package = |relative_path: &Path| -> CargoResult<bool> {
+ // include and exclude options are mutually exclusive.
+ if no_include_option {
+ match ignore_exclude.matched_path_or_any_parents(
+ relative_path,
+ /* is_dir */ false,
+ ) {
+ Match::None => Ok(true),
+ Match::Ignore(_) => Ok(false),
+ Match::Whitelist(pattern) => Err(CargoError::from(format!(
+ "exclude rules cannot start with `!`: {}",
+ pattern.original()
+ ))),
+ }
+ } else {
+ match ignore_include.matched_path_or_any_parents(
+ relative_path,
+ /* is_dir */ false,
+ ) {
+ Match::None => Ok(false),
+ Match::Ignore(_) => Ok(true),
+ Match::Whitelist(pattern) => Err(CargoError::from(format!(
+ "include rules cannot start with `!`: {}",
+ pattern.original()
+ ))),
+ }
+ }
+ };
+
+ // matching to paths
+
+ let mut filter = |path: &Path| -> CargoResult<bool> {
+ let relative_path = util::without_prefix(path, root).unwrap();
+ let glob_should_package = glob_should_package(relative_path);
+ let ignore_should_package = ignore_should_package(relative_path)?;
+
+ if glob_should_package != ignore_should_package {
+ if glob_should_package {
+ if no_include_option {
+ self.config
+ .shell()
+ .warn(format!(
+ "Pattern matching for Cargo's include/exclude fields is changing and \
+ file `{}` WILL be excluded in the next Cargo version.\n\
+ See https://github.com/rust-lang/cargo/issues/4268 for more info",
+ relative_path.display()
+ ))?;
+ } else {
+ self.config
+ .shell()
+ .warn(format!(
+ "Pattern matching for Cargo's include/exclude fields is changing and \
+ file `{}` WILL NOT be included in the next Cargo version.\n\
+ See https://github.com/rust-lang/cargo/issues/4268 for more info",
+ relative_path.display()
+ ))?;
+ }
+ } else {
+ if no_include_option {
+ self.config
+ .shell()
+ .warn(format!(
+ "Pattern matching for Cargo's include/exclude fields is changing and \
+ file `{}` WILL NOT be excluded in the next Cargo version.\n\
+ See https://github.com/rust-lang/cargo/issues/4268 for more info",
+ relative_path.display()
+ ))?;
+ } else {
+ self.config
+ .shell()
+ .warn(format!(
+ "Pattern matching for Cargo's include/exclude fields is changing and \
+ file `{}` WILL be included in the next Cargo version.\n\
+ See https://github.com/rust-lang/cargo/issues/4268 for more info",
+ relative_path.display()
+ ))?;
+ }
+ }
}
+
+ // Update to ignore_should_package for Stage 2
+ Ok(glob_should_package)
};
// attempt git-prepopulate only if no `include` (rust-lang/cargo#4135)
- if include.is_empty() {
+ if no_include_option {
if let Some(result) = self.discover_git_and_list_files(pkg, root, &mut filter) {
return result;
}
}
-
self.list_files_walk(pkg, &mut filter)
}
fn discover_git_and_list_files(&self,
pkg: &Package,
root: &Path,
- filter: &mut FnMut(&Path) -> bool)
+ filter: &mut FnMut(&Path) -> CargoResult<bool>)
-> Option<CargoResult<Vec<PathBuf>>> {
// If this package is in a git repository, then we really do want to
// query the git repository as it takes into account items such as
}
fn list_files_git(&self, pkg: &Package, repo: git2::Repository,
- filter: &mut FnMut(&Path) -> bool)
+ filter: &mut FnMut(&Path) -> CargoResult<bool>)
-> CargoResult<Vec<PathBuf>> {
warn!("list_files_git {}", pkg.package_id());
let index = repo.index()?;
let untracked = statuses.iter().filter_map(|entry| {
match entry.status() {
git2::STATUS_WT_NEW => Some((join(root, entry.path_bytes()), None)),
- _ => None
+ _ => None,
}
});
ret.extend(files.into_iter());
}
Err(..) => {
- PathSource::walk(&file_path, &mut ret, false,
- filter)?;
+ PathSource::walk(&file_path, &mut ret, false, filter)?;
}
}
- } else if (*filter)(&file_path) {
+ } else if (*filter)(&file_path)? {
// We found a file!
warn!(" found {}", file_path.display());
ret.push(file_path);
}
}
- fn list_files_walk(&self, pkg: &Package, filter: &mut FnMut(&Path) -> bool)
+ fn list_files_walk(&self, pkg: &Package, filter: &mut FnMut(&Path) -> CargoResult<bool>)
-> CargoResult<Vec<PathBuf>> {
let mut ret = Vec::new();
PathSource::walk(pkg.root(), &mut ret, true, filter)?;
}
fn walk(path: &Path, ret: &mut Vec<PathBuf>,
- is_root: bool, filter: &mut FnMut(&Path) -> bool) -> CargoResult<()>
+ is_root: bool, filter: &mut FnMut(&Path) -> CargoResult<bool>)
+ -> CargoResult<()>
{
if !fs::metadata(&path).map(|m| m.is_dir()).unwrap_or(false) {
- if (*filter)(path) {
+ if (*filter)(path)? {
ret.push(path.to_path_buf());
}
return Ok(())
if !is_root && fs::metadata(&path.join("Cargo.toml")).is_ok() {
return Ok(())
}
- for dir in fs::read_dir(path)? {
- let dir = dir?.path();
- let name = dir.file_name().and_then(|s| s.to_str());
+
+ // For package integration tests, we need to sort the paths in a deterministic order to
+ // be able to match stdout warnings in the same order.
+ //
+ // TODO: Drop collect and sort after transition period and dropping wraning tests.
+ // See <https://github.com/rust-lang/cargo/issues/4268>
+ // and <https://github.com/rust-lang/cargo/pull/4270>
+ let mut entries: Vec<fs::DirEntry> = fs::read_dir(path)?.map(|e| e.unwrap()).collect();
+ entries.sort_by(|a, b| a.path().as_os_str().cmp(b.path().as_os_str()));
+ for entry in entries {
+ let path = entry.path();
+ let name = path.file_name().and_then(|s| s.to_str());
// Skip dotfile directories
if name.map(|s| s.starts_with('.')) == Some(true) {
continue
_ => {}
}
}
- PathSource::walk(&dir, ret, false, filter)?;
+ PathSource::walk(&path, ret, false, filter)?;
}
Ok(())
}
use serde_json;
use toml;
use registry;
+use ignore;
error_chain! {
types {
foreign_links {
ParseSemver(semver::ReqParseError);
Semver(semver::SemVerError);
+ Ignore(ignore::Error);
Io(io::Error);
SerdeJson(serde_json::Error);
TomlSer(toml::ser::Error);
&CargoErrorKind::CrateRegistry(_) => true,
&CargoErrorKind::ParseSemver(_) |
&CargoErrorKind::Semver(_) |
+ &CargoErrorKind::Ignore(_) |
&CargoErrorKind::Io(_) |
&CargoErrorKind::SerdeJson(_) |
&CargoErrorKind::ParseInt(_) |
name = "foo"
version = "0.0.1"
authors = []
- exclude = ["*.txt"]
+ exclude = [
+ "*.txt",
+ # file in root
+ "file_root_1", # NO_CHANGE (ignored)
+ "/file_root_2", # CHANGING (packaged -> ignored)
+ "file_root_3/", # NO_CHANGE (packaged)
+ "file_root_4/*", # NO_CHANGE (packaged)
+ "file_root_5/**", # NO_CHANGE (packaged)
+ # file in sub-dir
+ "file_deep_1", # CHANGING (packaged -> ignored)
+ "/file_deep_2", # NO_CHANGE (packaged)
+ "file_deep_3/", # NO_CHANGE (packaged)
+ "file_deep_4/*", # NO_CHANGE (packaged)
+ "file_deep_5/**", # NO_CHANGE (packaged)
+ # dir in root
+ "dir_root_1", # CHANGING (packaged -> ignored)
+ "/dir_root_2", # CHANGING (packaged -> ignored)
+ "dir_root_3/", # CHANGING (packaged -> ignored)
+ "dir_root_4/*", # NO_CHANGE (ignored)
+ "dir_root_5/**", # NO_CHANGE (ignored)
+ # dir in sub-dir
+ "dir_deep_1", # CHANGING (packaged -> ignored)
+ "/dir_deep_2", # NO_CHANGE
+ "dir_deep_3/", # CHANGING (packaged -> ignored)
+ "dir_deep_4/*", # CHANGING (packaged -> ignored)
+ "dir_deep_5/**", # CHANGING (packaged -> ignored)
+ ]
"#)
.file("src/main.rs", r#"
fn main() { println!("hello"); }
"#)
.file("bar.txt", "")
- .file("src/bar.txt", "");
+ .file("src/bar.txt", "")
+ // file in root
+ .file("file_root_1", "")
+ .file("file_root_2", "")
+ .file("file_root_3", "")
+ .file("file_root_4", "")
+ .file("file_root_5", "")
+ // file in sub-dir
+ .file("some_dir/file_deep_1", "")
+ .file("some_dir/file_deep_2", "")
+ .file("some_dir/file_deep_3", "")
+ .file("some_dir/file_deep_4", "")
+ .file("some_dir/file_deep_5", "")
+ // dir in root
+ .file("dir_root_1/some_dir/file", "")
+ .file("dir_root_2/some_dir/file", "")
+ .file("dir_root_3/some_dir/file", "")
+ .file("dir_root_4/some_dir/file", "")
+ .file("dir_root_5/some_dir/file", "")
+ // dir in sub-dir
+ .file("some_dir/dir_deep_1/some_dir/file", "")
+ .file("some_dir/dir_deep_2/some_dir/file", "")
+ .file("some_dir/dir_deep_3/some_dir/file", "")
+ .file("some_dir/dir_deep_4/some_dir/file", "")
+ .file("some_dir/dir_deep_5/some_dir/file", "")
+ ;
assert_that(p.cargo_process("package").arg("--no-verify").arg("-v"),
- execs().with_status(0).with_stderr("\
+ execs().with_status(0).with_stdout("").with_stderr("\
[WARNING] manifest has no description[..]
See http://doc.crates.io/manifest.html#package-metadata for more info.
[PACKAGING] foo v0.0.1 ([..])
+[WARNING] [..] file `dir_root_1[/]some_dir[/]file` WILL be excluded [..]
+See [..]
+[WARNING] [..] file `dir_root_2[/]some_dir[/]file` WILL be excluded [..]
+See [..]
+[WARNING] [..] file `dir_root_3[/]some_dir[/]file` WILL be excluded [..]
+See [..]
+[WARNING] [..] file `file_root_2` WILL be excluded [..]
+See [..]
+[WARNING] [..] file `some_dir[/]dir_deep_1[/]some_dir[/]file` WILL be excluded [..]
+See [..]
+[WARNING] [..] file `some_dir[/]dir_deep_3[/]some_dir[/]file` WILL be excluded [..]
+See [..]
+[WARNING] [..] file `some_dir[/]dir_deep_4[/]some_dir[/]file` WILL be excluded [..]
+See [..]
+[WARNING] [..] file `some_dir[/]dir_deep_5[/]some_dir[/]file` WILL be excluded [..]
+See [..]
+[WARNING] [..] file `some_dir[/]file_deep_1` WILL be excluded [..]
+See [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
[ARCHIVING] [..]
[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+[ARCHIVING] [..]
+"));
+
+ assert_that(&p.root().join("target/package/foo-0.0.1.crate"), existing_file());
+
+ assert_that(p.cargo("package").arg("-l"),
+ execs().with_status(0).with_stdout("\
+Cargo.toml
+dir_root_1[/]some_dir[/]file
+dir_root_2[/]some_dir[/]file
+dir_root_3[/]some_dir[/]file
+file_root_2
+file_root_3
+file_root_4
+file_root_5
+some_dir[/]dir_deep_1[/]some_dir[/]file
+some_dir[/]dir_deep_2[/]some_dir[/]file
+some_dir[/]dir_deep_3[/]some_dir[/]file
+some_dir[/]dir_deep_4[/]some_dir[/]file
+some_dir[/]dir_deep_5[/]some_dir[/]file
+some_dir[/]file_deep_1
+some_dir[/]file_deep_2
+some_dir[/]file_deep_3
+some_dir[/]file_deep_4
+some_dir[/]file_deep_5
+src[/]main.rs
"));
}